package com.miaomiao.controller.system;

import cn.hutool.log.Log;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.miaomiao.common.RedisPrefix;
import com.miaomiao.common.Result;
import com.miaomiao.domain.system.*;
import com.miaomiao.exception.ServiceException;
import com.miaomiao.mapper.system.MenuMapper;
import com.miaomiao.mapper.system.RoleMenuMapper;
import com.miaomiao.service.system.MenuService;
import com.miaomiao.service.system.RoleService;
import com.miaomiao.utils.RedisCache;
import com.miaomiao.utils.SecurityUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/role")
@Api(tags = "角色管理")
public class RoleController {

    @Resource
    private RoleService roleService;

    @Autowired
    private MenuService menuService;
    @Autowired
    private RoleMenuMapper roleMenuMapper;

    @Autowired
    private RedisCache redisCache;

    @GetMapping("/list")
    @PreAuthorize("@ss.hasPermis('system:role')")
    @ApiOperation("获取角色信息列表")
    public Result getRoleList(@RequestParam int currentPage, int pageSize, Role role){
        Page<Role> page = new Page<>(currentPage,pageSize);
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        if(!Objects.isNull(role.getRoleName()))  queryWrapper.like(Role::getRoleName,role.getRoleName());
        if(!Objects.isNull(role.getRoleKey()))  queryWrapper.like(Role::getRoleKey,role.getRoleKey());
        if(!Objects.isNull(role.getStatus()))  queryWrapper.eq(Role::getStatus,role.getStatus());
        queryWrapper.orderByAsc(Role::getRoleSort);
        roleService.page(page,queryWrapper);
        return Result.success(page);
    }

    @GetMapping("/select")
    @PreAuthorize("@ss.hasPermis('system:role')")
    @ApiOperation("获取角色信息列表（用于新增用户分配角色）")
    public Result getRoleSelectList(){
        List<Role> roleList = roleService.list();
        return Result.success(roleList.stream().map(RoleSelect::new).collect(Collectors.toList()));
    }

    @GetMapping("/user")
    @PreAuthorize("@ss.hasPermis('system:role')")
    @ApiOperation("根据userId查询用户角色")
    public Result getUserRoles(@RequestParam Long userId){
        List<Role> roleList = roleService.getUserRoles(userId);
        return Result.success(roleList);
    }

    @GetMapping("/menus")
    @PreAuthorize("@ss.hasPermis('system:role')")
    @ApiOperation("根据roleId查询用户菜单")
    public Result getRoleAndMenus(@RequestParam Long roleId){
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Role::getRoleId,roleId);
        Role role = roleService.getOne(queryWrapper);
        List<Menu> menus = menuService.getRoleMenus(roleId);
        return Result.success(new RoleVo(role,menus));
    }

    @PostMapping
    @PreAuthorize("@ss.hasPermis('system:role')")
    @Transactional
    @ApiOperation("新增角色和菜单权限")
    public Result addRoleAndMenus(@RequestBody RoleMenuIds roleMenuIds){
        Role role = roleMenuIds.getRole();
        List<RoleMenu> roleMenus = roleMenuIds.getRoleMenus();
        boolean save;
        try{
            save = roleService.save(role);
            for(RoleMenu roleMenu:roleMenus){
                roleMenu.setRoleId(role.getRoleId());
            }
            save = save && roleMenuMapper.batchRoleMenu(roleMenus) > 0;
        }catch (RuntimeException e){
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.error("新增失败");
        }
        if(save) {
            redisCache.deleteObject(RedisPrefix.ROUTERS_PRE + SecurityUtils.getUserId());
            return  Result.success("新增成功");
        }
        return Result.error("新增失败");
    }

    @PutMapping
    @PreAuthorize("@ss.hasPermis('system:role')")
    @Transactional
    @ApiOperation("修改角色和菜单权限")
    public Result updateRoleAndMenus(@RequestBody RoleMenuIds roleMenuIds){
        List<RoleMenu> roleMenus = roleMenuIds.getRoleMenus();
        boolean update;
        try{
            Role role = roleMenuIds.getRole();
            LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Role::getRoleId,role.getRoleId());
            update = roleMenuMapper.deleteRoleMenuByRoleId(role.getRoleId()) > 0
                    && roleMenuMapper.batchRoleMenu(roleMenus) > 0;
            role.setRoleId(null);
            update = update && roleService.update(role,queryWrapper);
        }catch (RuntimeException e){
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.error("修改失败");
        }
        if(update) {
            redisCache.deleteObject(RedisPrefix.ROUTERS_PRE + SecurityUtils.getUserId());
            return Result.success("修改成功");
        }
        return Result.error("修改失败");
    }

    @DeleteMapping("/{roleIds}")
    @PreAuthorize("@ss.hasPermis('system:role')")
    @Transactional
    @ApiOperation("删除角色和菜单权限")
    public Result deleteRoleAndMenus(@PathVariable List<Long> roleIds){
        if(roleIds.contains(1L)){
            throw new ServiceException("超级管理员角色不能删除");
        }
        boolean remove;
        try{
            LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(Role::getRoleId,roleIds);
            remove = roleService.remove(queryWrapper)
                    && roleMenuMapper.deleteRoleMenu(roleIds) > 0;
        }catch (RuntimeException e){
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.error("删除失败");
        }
        if(remove) {
            redisCache.deleteObject(RedisPrefix.ROUTERS_PRE + SecurityUtils.getUserId());
            return  Result.success("删除成功");
        }
        return Result.error("删除失败");
    }

    @PutMapping("/change")
    @PreAuthorize("@ss.hasPermis('system:role')")
    @ApiOperation("修改角色状态")
    public Result changeStatus(@RequestParam Long roleId){
        if(roleId == 1L){
            return Result.error("超级管理员角色不能修改");
        }
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Role::getRoleId,roleId);
        Role role = roleService.getOne(queryWrapper);
        Role newRole = new Role();
        //切换状态
        newRole.setStatus(!role.getStatus());
        boolean update = roleService.update(newRole, queryWrapper);
        if(update) {
            redisCache.deleteObject(RedisPrefix.ROUTERS_PRE + SecurityUtils.getUserId());
            return Result.success("切换成功");
        }
        return Result.error("切换失败");
    }
}
